import time
import wx
import vtk
import math
import numpy
import vtktudoss
try:
    import extended.BaseCalc as BaseCalc
except ImportError:
    import BaseCalc


def create(parent, renderwindow, primaryrenderer):
    return PlotOverlay(parent, renderwindow, primaryrenderer)
    
class PlotOverlay:
    def __init__(self, parent, renderwindow, primaryrenderer):
        print "PCP overlay module loaded."        
        self.parent = parent
        self.renderwindow = renderwindow.GetRenderWindow()
        self.interactorstyle = renderwindow.GetInteractorStyle()
        self.renX = primaryrenderer
        self.baseCalc = BaseCalc.create(self, self)
        self.windowsize = renderwindow.GetSize()
         
        self.labellist = []
        self.guidelineCollection = []
        
        self.parent.renwini3.Unbind(wx.EVT_RIGHT_DOWN)
        self.parent.renwini3.Bind(wx.EVT_RIGHT_DOWN, self.PCP_rightclick)
        
    def PCP_rightclick(self, event):
        x,y = event.GetX(), event.GetY()
        vtk_y = self.parent.flip_y(y)
        coords = self.Get3DCoords([x, vtk_y, 0.0])
        for i in range(1, len(self.parent.parent.Filters.plottedAngles)):
            if coords[0]<(i+1) and coords[0]>(i):
                self.parent.AddScatter(i-1, i)

        
    def RefreshOverlay(self):
        labellistlength = len(self.labellist)
        for i in range(0, labellistlength):
            self.renX.RemoveActor2D(self.labellist.pop(0))
        for i in range(0, len(self.guidelineCollection)):
            self.renX.RemoveActor(self.guidelineCollection.pop(0))
        
        self.PutLabels()
        self.CreateGuidelines()
        
    def Get2DCoords(self, pos):        
        outputpoint = [0.0,0.0,0.0]
        self.interactorstyle.ComputeWorldToDisplay(self.renX, pos[0], pos[1], pos[2], outputpoint)
        return outputpoint

    def Get3DCoords(self, pos):        
        outputpoint = [0.0,0.0,0.0, 0.0]
        self.interactorstyle.ComputeDisplayToWorld(self.renX, pos[0], pos[1], pos[2], outputpoint)
        return outputpoint
        
    def PutLabels(self):        
        Filters = self.parent.parent.Filters
        windowsize = self.renderwindow.GetSize()
        positionYa = windowsize[1]-30.0
        positionYb = 35.0
        minX = 70.0
        maxX = windowsize[0] - 100.0
        #~ for i in range(0, len(self.parent.parent.Filters.jointAngleCollection)):            
        i=0
        for stanceID in Filters.plottedAngles:            
            for filter in Filters.jointAngleCollection:
                if filter['stanceID'] == stanceID:
                    positionX = self.Get2DCoords((i + 1, 0.0, 0.0))[0]
                    if positionX < minX:
                        if positionX < 0.0:
                            positionX = 0.0
                        opacity = positionX / minX
                    elif positionX > maxX:
                        if positionX > windowsize[0]:
                            positionX = windowsize[0]
                        opacity = (positionX - maxX) / (windowsize[0] - maxX)
                    else:
                        opacity = 1.0
                    #~ print opacity
                    #~ if 0.0 < positionX < windowsize[0]:
                    if 70.0 < positionX < windowsize[0]-100:
                        description = filter['description']
                        textActor = vtk.vtkTextActor3D()
                        textprop = vtk.vtkTextProperty()
                        textprop.SetFontFamilyToArial()
                        textprop.SetFontSize(288)
                        textprop.ShadowOn()
                        textprop.SetOpacity(opacity)
                        #~ textprop.ShadowOn()
                        #~ textprop.BoldOn()
                        textprop.SetJustificationToCentered()
                        #~ textprop.SetVerticalJustificationToBottom()
                        textActor.SetTextProperty(textprop)
                        #~ if i%2 == 0:
                        coords = self.Get3DCoords([positionX, positionYa, 0.0])
                        #~ else:
                            #~ coords = self.Get3DCoords([positionX, positionYb, 0.0])
                        coords[2] = 0.0
                        
                        ##~ textActor.RotateZ(22)
                        textActor.SetScale(0.0005)
                        textActor.SetInput(description)
                        self.labellist.append(textActor)
                        self.renX.AddActor(textActor)
                        bbox = [0,0,0,0]
                        textActor.GetBoundingBox (bbox)
                        textActor.SetPosition(coords[0] - bbox[1]/(2000.0), coords[1] + bbox[2]/(1000.0), coords[2])
                        self.PutValues(i, opacity)
            i=i+1

    def PutValues(self, i, opacity):
        yInd  = [[0.0, 180.0], [-0.5, 90.0], [-1.0, 0.0], [-1.5, -90.0], [-2.0, -180.0]]
        windowsize = self.renderwindow.GetSize()
        for yPair in yInd:
            coord2D = self.Get2DCoords((i+1, yPair[0], 0.0))
            coord2Dx = coord2D[0]
            coord2Dy = coord2D[1]
            
            if 25.0 < coord2Dy < (windowsize[1]-40.0):
                textActor = vtk.vtkTextActor3D()
                textprop = vtk.vtkTextProperty()
                textprop.SetFontFamilyToArial()
                textprop.SetFontSize(144)
                textprop.ShadowOn()
                textprop.SetOpacity(opacity)
                textprop.SetJustificationToCentered()
                textprop.SetColor(0.8, 0.8 ,0.8)
                textActor.SetTextProperty(textprop)
                
                coords = self.Get3DCoords([coord2Dx + 4, coord2Dy  + 4, 0.0])
                coords[2] = 0.0
                textActor.SetPosition(coords[0], coords[1], coords[2])
                ##~ textActor.RotateZ(22)
                textActor.SetScale(0.0007)
                textActor.SetInput(str(yPair[1]))
                self.labellist.append(textActor)
                self.renX.AddActor(textActor)
        
    def CreateGuidelines(self): 
   
        nrParameters = len(self.parent.parent.Filters.plottedAngles)
        #~ linelength = max(1.0, float(nrParameters-1.0))    #14.0
        #~ if linelength>0.0:
            #~ dashes = int(linelength * 10)
            #~ dashlenght = linelength/(dashes*2.0) 
            #~ dashedPoints = vtk.vtkPoints()
            #~ dashedPoints.SetNumberOfPoints(dashes*2)

            #~ for i in range(0, dashes):
                #~ dashedPoints.InsertPoint(i, 1.0 + dashlenght * 2*i, 0.0, 0.01)
                #~ dashedPoints.InsertPoint(i, 1.0 + dashlenght * 2*i+ dashlenght, 0.0, 0.01)
                
            #~ dashedLines = vtk.vtkCellArray()
            #~ for j in range(0, dashes):
                #~ dashedLines.InsertNextCell(2)		
                #~ dashedLines.InsertCellPoint(2*j)
                #~ dashedLines.InsertCellPoint(2*j+1)

            #~ dashedGuideline = vtk.vtkPolyData()
            #~ dashedGuideline.SetLines(dashedLines)	
            #~ dashedGuideline.SetPoints(dashedPoints)
            #~ dashedGuideline.Update()
                        
            #~ for i in range(1, 4): #3 lines on top of each other
                #~ dashedCopy = vtk.vtkPolyData()
                #~ dashedCopy.DeepCopy(dashedGuideline)
                #~ dashedMapper1 = vtktud.vtktudExtendedOpenGLPolyDataMapper()
                #~ dashedMapper1.SetInput(dashedCopy)
                #~ dashedActor1 = vtk.vtkActor()
                #~ dashedActor1.SetMapper(dashedMapper1)
                #~ dashedActor1.GetProperty().SetOpacity(0.5)
                #~ dashedActor1.GetProperty().SetDiffuseColor(0.75, 0.75, 0.0)
                #~ dashedActor1.SetPosition(0.0, -i * 0.5, 0.0)
                #~ self.renX.AddActor(dashedActor1)
                #~ self.guidelineCollection.append(dashedActor1)

        windowsize = self.renderwindow.GetSize()
        positionYa = windowsize[1]-70.0
        positionYb = 70.0
        highpt = self.Get3DCoords((0, positionYa, 0))
        lowpt = self.Get3DCoords((0, positionYb, 0))
        linelength = 2.0
        verticalPoints = vtk.vtkPoints()
        verticalPoints.SetNumberOfPoints(2)
        verticalPoints.InsertPoint(0, 0.0, highpt[1], 0.01)
        verticalPoints.InsertPoint(1, 0.0, lowpt[1], 0.01)
        verticalLines = vtk.vtkCellArray()
        verticalLines.InsertNextCell(2)		
        verticalLines.InsertCellPoint(0)
        verticalLines.InsertCellPoint(1)
        verticalGuideline = vtk.vtkPolyData()
        verticalGuideline.SetLines(verticalLines)	
        verticalGuideline.SetPoints(verticalPoints)
        verticalGuideline.Update()
        
        for i in range(0,nrParameters):
            verticalMapper1 = vtktudoss.vtktudExtendedOpenGLPolyDataMapper()
            verticalMapper1.SetInput(verticalGuideline)
            verticalActor1 = vtk.vtkActor()
            verticalActor1.SetMapper(verticalMapper1)
            verticalActor1.GetProperty().SetOpacity(0.5)
            verticalActor1.GetProperty().SetDiffuseColor(0.75, 0.75, 0.0)
            verticalActor1.SetPosition(1.0 + i, 0.0, 0.0)
            self.renX.AddActor(verticalActor1)
            self.guidelineCollection.append(verticalActor1)
                    
            

        
    def PutSelectionOutline(self):
        pass

    
    
    